#!/usr/bin/env python
#-*- coding: utf-8 -*-

import sys
import os
import argparse

## import gtk or force cli
try:
    import gtk
    NO_GTK = False
except:
    NO_GTK = True    
    
    
PRETTY = False
try:
    import lxml.etree as etree
    PRETTY = True
except:
    import xml.etree.ElementTree as etree

class omnibus_hello(object):
    CLI = 1
    GUI = 2
    
    def __init__(self, config_dir, ui):
        self.config_dir = config_dir
        self.config_file = os.path.join(config_dir, "config.xml")
        self.ui = ui
        
        ## BRANCH: create GUI
        if ( ui == self.GUI ):
            self.builder = gtk.Builder()
            RESSOURCE_DIR = os.path.dirname(sys.argv[0])
            if ( RESSOURCE_DIR ):
                RESSOURCE_DIR += "/"
            self.builder.add_from_file(RESSOURCE_DIR + "hello.glade")
            self.builder.connect_signals(self)
            
            self.builder.get_object('port_spin').set_value(41322)
        ## BRANCH: CLI
        else:
            print
            self.username = raw_input("Enter username: ")
            print
            self.create_config()

    def cli(self):
        return self.ui == self.CLI
        
    def run(self):
        try:
            if ( ui == self.GUI ):
                gtk.main()
        except KeyboardInterrupt:
            pass
    
    def quit(self):
        if ( self.ui == self.GUI ):
            gtk.main_quit()


    def on_main_window_delete_event(self, *args):
        self.quit()
        
    def on_cancel_button_clicked(self, action, *args):
        self.quit()
        

    def on_port_check_toggled(self, button, *_):
        spinner = self.builder.get_object('port_spin')
        spinner.set_sensitive(button.get_active())

    def on_name_entry_changed(self, button, *_):
        if ( len(self.builder.get_object('name_entry').get_text().strip()) >= 3 ):
            self.builder.get_object("name_error").set_visible(False)
        
    def on_ok_button_clicked(self, action, *args):
        self.create_config()
        
    def create_config(self):
        top = etree.Element('omnibus')
        top.attrib["config-version"] = "1"
        
        ## username
        if ( self.cli() ):
            user_name = self.username
        else:
            user_name = self.builder.get_object('name_entry').get_text().strip()
            
        # sanity check
        if ( len(user_name) < 3 ):
            print "Username too short!"
            
            if ( not self.cli() ):
                self.builder.get_object("name_error").set_visible(True)
    
            return
        name = etree.SubElement(top, 'user_name')
        name.text = unicode(user_name)
        
        ## endpoints
        endpoints = etree.SubElement(top, 'listen_on')
        
        # TCP-Port
        tcp_port = etree.SubElement(endpoints, 'tcp_port')
        if ( self.cli() or not self.builder.get_object('port_check').get_active() ):
            tcp_port.text = "DEFAULT"
        else:
            tcp_port.text = str(self.builder.get_object('port_spin').get_value_as_int())
            
        # Bluetooth
        bluetooth = etree.SubElement(endpoints, 'bluetooth_channel')
        if ( self.cli() or self.builder.get_object('bluetooth_default').get_active() ) :
            bluetooth.text = "DEFAULT"
        elif ( self.builder.get_object('bluetooth_enabled').get_active() ):
            bluetooth.text = "YES"
        elif ( self.builder.get_object('bluetooth_disabled').get_active() ):
            bluetooth.text = "NO"
            
        # devices (no options)
        etree.SubElement(endpoints, 'ip').text = "DEFAULT"
        etree.SubElement(endpoints, 'bluetooth_device').text = "DEFAULT"

        ## bootstrap
        bootstrap = etree.SubElement(top, 'bootstrap')
        
        # direct
        direct = etree.SubElement(bootstrap, 'direct')
        server_defaults = etree.SubElement(direct, 'default_items')
        if ( self.cli() or self.builder.get_object('server_check').get_active() ) :
            server_defaults.text = "YES"
        else:
            server_defaults.text = "NO"

        # lan
        broadcast = etree.SubElement(bootstrap, 'broadcast')
        mdns = etree.SubElement(bootstrap, 'mdns')
        if ( self.cli() or self.builder.get_object('broadcast_check').get_active() ) :
            broadcast.text = "DEFAULT"
            mdns.text = "DEFAULT"
        else:
            broadcast.text = "NO"
            mdns.text = "NO"
        
        # sdp
        sdp = etree.SubElement(bootstrap, 'sdp')
        if ( self.cli() or self.builder.get_object('bluetooth_default').get_active() ) :
            sdp.text = "DEFAULT"
        elif ( self.builder.get_object('bluetooth_enabled').get_active() ):
            sdp.text = "YES"
        elif ( self.builder.get_object('bluetooth_disabled').get_active() ):
            sdp.text = "NO"

        ## flow control (no options)
        etree.SubElement(top, 'flow_control').text = "DEFAULT"
        
        
        ## write config.xml
        tree = etree.ElementTree(top)
        
        # Ordner anlegen, wenn er nicht existiert. (XXX Soll nicht unbedingt so bleiben.)
        if ( not os.path.exists(self.config_dir) ):
            os.makedirs(self.config_dir)
        
        if ( PRETTY ):    
            tree.write(self.config_file, encoding="utf-8", pretty_print=True)
#            tree.write(sys.stdout, encoding="utf-8", pretty_print=True)    ## für debug, auf stdout ausgeben
        else:
            tree.write(self.config_file, encoding="utf-8")
        
        ## create std dirs: incoming, public, private
        ## (incoming/ will also always created by garage,
        ## but public and private should be intentionally deletable (omnibus-bin will handle this)
        subdirs = ("incoming", "public", "private")
        for subdir in subdirs:
            full_subdir = os.path.join(self.config_dir, subdir)
            if ( not os.path.isdir(full_subdir) ):
                os.makedirs(full_subdir)
        
        ## create start.sh  ## FIXME
##        self.create_start_sh()
        
        ## create desktop launcher  ## FIXME
##        if ( self.builder.get_object('launcher_check').get_active() ):
##            self.create_launcher()
        
        ## install libs  ## FIXME
##        if ( self.builder.get_object('libs_check').get_active() ):
##            os.system("xterm -e program/hello/install_libs.sh")
        
        ## quit
        self.quit()
        
        
    ## this function creates the start.sh
    def create_start_sh(self):
        raise Exception("Mario, programmier dieses Programm endlich fertig!!") ## FIXME
        
###        # read
###        infile = open('program/hello/start-template.sh','r')
###        s = infile.read()
###        infile.close()
###        
###        # modify
###        x = s.replace("/*BASE*/", os.getcwd())
###        
###        # write / replace start.sh
###        os.remove('start.sh')
###        outfile = open('start.sh','w')
###        outfile.write(x)
###        outfile.close()
###        os.chmod('start.sh', 0744)
        

    ## this function creates the desktop launcher
    def create_launcher(self):
        raise Exception("Mario, programmier dieses Programm endlich fertig!!") ## FIXME
        
###        # read
###        infile = open('program/hello/launcher-template.txt','r')
###        s = infile.read()
###        infile.close()
###        
###        # modify
###        y = s.replace("/*PATH*/", os.getcwd() + "/start.sh")
###        x = y.replace("/*PICPATH*/", os.getcwd() + "/program/client/pics/omnibus-icon-v3.svg")
###        
###        # write / replace start.sh
###        launcher_path = os.path.expanduser("~") + '/Desktop/omnibus.desktop'
###        outfile = open(launcher_path,'w')
###        outfile.write(x)
###        outfile.close()
###        os.chmod(launcher_path, 0744)
    
    

## main ##
if __name__ == '__main__':
    
    # handle arguments 
    parser = argparse.ArgumentParser(description='Omnibus Hello', add_help=True)
    parser.add_argument('--config', '-c', action="store", dest="config_dir",
                        default=os.path.expanduser("~/.omnibus/"))
    # TODO: Maybe find a better default, especially when starting from a "folder"
    parser.add_argument('--cli', action="store_true")
    parser.add_argument('--gui', action="store_true")
    
    args = parser.parse_args()
    
    ## cli or gui
    if ( NO_GTK or args.cli ):
        ui = omnibus_hello.CLI
    else:
        ui = omnibus_hello.GUI
    
    app = omnibus_hello(args.config_dir, ui)
    app.run()
    
